package org.koron.ebs.util.field;

import java.util.LinkedList;
import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.regex.Pattern;

/**
 * Html标签，用来生成HTML字符串用.
 * 
 * @author swan
 *
 */
public final class HtmlTag {
	/**
	 * 标签. 解析的时候，如果tag为空则只解析content,否则不解析content
	 */
	private String tag;
	/**
	 * 属性
	 */
	private TreeMap<String, String> attr = new TreeMap<>();
	/**
	 * 内含的标签
	 */
	private LinkedList<HtmlTag> list = new LinkedList<>();
	/**
	 * 具体内容
	 */
	private String content = "";

	/**
	 * 构造函数
	 * 
	 * @param tag 标签
	 */
	public HtmlTag(String tag) {
		this(tag, new TreeMap<String, String>());
	}

	/**
	 * 构造函数
	 * 
	 * @param tag 标签
	 * @param content 内容
	 */
	public HtmlTag(String tag, String content) {
		this(tag, new TreeMap<String, String>());
		this.content = content;
	}

	/**
	 * 构造函数
	 * 
	 * @param tag 标签
	 * @param attr 属性
	 */
	public HtmlTag(String tag, TreeMap<String, String> attr) {
		super();
		this.tag = tag == null ? "" : tag;
		if (attr != null)
			this.attr = attr;
	}

	/**
	 * 查找节点下的指定标签的节点集合.
	 * @param tag 标签,正则表达式
	 * @param recursion 找到符合的标签后，是否再找子集
	 * @return 一个包含所有标签集合的标签
	 */
	public HtmlTag find(String tag,boolean recursion) {
		HtmlTag tags = new HtmlTag("");
		if (Pattern.compile("^"+tag+"$").matcher(getTag()).find()) {
			tags.append(this);
			if(!recursion)
				return tags;
		}
		if (!getList().isEmpty()) {
			for (HtmlTag htmlTag : getList()) {
				tags.getList().addAll(htmlTag.find(tag,recursion).getList());
			}
		}
		return tags;
	}

	/**
	 * 设置属性
	 * 
	 * @param name 属性名
	 * @param value 属性值
	 * @return 标签
	 */
	public HtmlTag attr(String name, String value) {
		if (value == null)
			attr.remove(name);
		if (tag.isEmpty() && content.isEmpty()) {
			for (HtmlTag htmlTag : getList()) {
				htmlTag.attr(name, value);
			}
		} else
			attr.put(name, value);
		return this;
	}

	/**
	 * 批量设置属性
	 * 
	 * @param attrs 属性,二维数组,0为属性名,1为属性值
	 * @return 标签
	 */
	public HtmlTag attr(String[]... attrs) {
		if (attrs == null)
			return this;
		for (String[] attr : attrs) {
			if (attr != null && attr.length == 2)
				attr(attr[0], attr[1]);
		}
		return this;
	}

	/**
	 * 获取属性
	 * 
	 * @param name 属性名
	 * @return 标签
	 */
	public String attr(String name) {
		return attr.get(name);
	}

	/**
	 * 批量设置样式
	 * 
	 * @param csss 样式,二维数组,0为样式名1为样式值
	 * @return 标签
	 */
	public HtmlTag css(String[]... csss) {
		if (csss == null)
			return this;
		for (String[] css : csss) {
			if (css != null && css.length == 2)
				css(css[0], css[1]);
		}
		return this;
	}

	/**
	 * 设置css
	 * 
	 * @param name css名
	 * @param value 样式值
	 * @return 标签
	 */
	public HtmlTag css(String name, String value) {
		String style = attr("style");
		if (tag.isEmpty() && content.isEmpty()) {
			for (HtmlTag htmlTag : getList()) {
				htmlTag.css(name, value);
			}
		} else {
			if (style == null)
				attr("style", name + ":" + value);
			else
				attr("style", style + ";" + name + ":" + value);
		}
		return this;
	}

	/**
	 * 增加类
	 * 
	 * @param value 值
	 * @return 标签
	 */
	public HtmlTag addClass(String value) {
		if (tag.isEmpty() && content.isEmpty()) {
			for (HtmlTag htmlTag : getList()) {
				htmlTag.addClass(value);
			}
		} else {
			String className = attr("class");
			if (className == null)
				attr.put("class", value);
			else
				attr.put("class", className + " " + value);
		}
		return this;
	}

	/**
	 * 移除class
	 * 
	 * @param value class的名称
	 * @return 标签
	 */
	public HtmlTag removeClass(String value) {
		String className = attr("class");
		if (className != null)
			attr("class", className.replaceAll("value ", ""));
		return this;
	}

	/**
	 * 在子标签的尾部加上tag
	 * 
	 * @param tags 标签
	 * @return 父标签
	 */
	public HtmlTag append(HtmlTag... tags) {
		for (HtmlTag tag : tags) {
			list.add(tag);
		}
		return this;
	}

	/**
	 * 在子标签的头部加上tag
	 * 
	 * @param tags 标签
	 * @return 父标签
	 */
	public HtmlTag prepend(HtmlTag... tags) {
		for (HtmlTag tag : tags) {
			list.add(0, tag);
		}
		return this;
	}

	/**
	 * 在子标签的指定位置加上tag
	 * 
	 * @param index 加上标签的位置，如果大于原有
	 * @param tags 标签
	 * @return 父标签
	 */
	public HtmlTag addTag(final int index, HtmlTag... tags) {
		int pos = index;
		if (index <= 0)
			return prepend(tags);
		if (index > list.size() - 1)
			return append(tags);
		for (HtmlTag tag : tags) {
			list.add(pos, tag);
		}
		return this;
	}

	/**
	 * 生成HTML
	 * 
	 * @return html字符串
	 */
	public String html() {
		StringBuilder sb = new StringBuilder();
		if (tag.isEmpty()) {// 无标签
			if (content == null || content.trim().isEmpty()) {// 无内容
				for (HtmlTag tagBean : list) {
					if (tagBean != null)
						sb.append(tagBean.html());
				}
				return sb.toString();
			} else
				return content;// 如果没tag，直接返回内容
		}
		sb.append("<").append(tag);
		for (Entry<String, String> entry : attr.entrySet()) {
			if (entry.getValue() != null && !entry.getValue().equals(""))
				sb.append(" ").append(entry.getKey()).append("=\"" + entry.getValue() + "\"");
		}
		if (list.isEmpty())
			sb.append("/>");
		else {
			sb.append(">");
			for (HtmlTag tagBean : list) {
				if (tagBean != null)
					sb.append(tagBean.html());
			}
			sb.append("</").append(tag).append(">");
		}
		return sb.toString();
	}

	/**
	 * @return 获取标签
	 */
	public String getTag() {
		return tag;
	}

	/**
	 * @param tag 设置标签
	 */
	public void setTag(String tag) {
		this.tag = tag;
	}

	/**
	 * @return 获取属性
	 */
	public TreeMap<String, String> getAttrs() {
		return attr;
	}

	/**
	 * @param map 设置属性
	 */
	public void setAttrs(TreeMap<String, String> attr) {
		this.attr = attr;
	}

	/**
	 * @return 获取内含的标签
	 */
	public LinkedList<HtmlTag> getList() {
		return list;
	}

	/**
	 * @param list 设置内含的标签
	 */
	public void setList(LinkedList<HtmlTag> list) {
		this.list = list;
	}

	/**
	 * @return 获取具体内容
	 */
	public String getContent() {
		return content;
	}

	/**
	 * @param content 设置具体内容
	 */
	public HtmlTag setContent(String content) {
		this.content = content;
		return this;
	}
}
